<?php
/**
 * This file is part of Hyperf Mall.
 *
 * @link     https://gitee.com/scwlkj/hyperf_mall
 * @contact  hyperf_mall@163.com
 */

declare(strict_types=1);

namespace App\Repository;

use App\Constants\CouponConstants;
use App\Exception\BaseException;
use App\Model\CouponReceiveModel;
use App\Service\Member\MemberService;
use App\Utils\DB;
use Hyperf\Di\Annotation\Inject;

class CouponReceiveRepository extends BaseRepository
{
    /**
     * @Inject
     * @var CouponReceiveModel
     */
    protected $model;

    /**
     * @Inject
     * @var CouponRepository
     */
    protected CouponRepository $couponRepository;

    /**
     * @Inject
     * @var CouponGoodsRepository
     */
    protected CouponGoodsRepository $couponGoodsRepository;

    /**
     * @Inject
     * @var MemberService
     */
    protected MemberService $memberService;

    public function baseAdd($data)
    {
        $field = ['name','free_type','goods_type','coupon_price','price','residue_num','id','receive_after_day','receive_start_time','receive_end_time'];
        $condition = [
            'id'=>$data['id'],
            'status'=>CouponConstants::COUPON_ENABLE,
            ['start_time','<', time()],
            ['end_time','>', time()]
        ];
        $re = $this->couponRepository->getOne($condition, $field);
        if(empty($re)){
            throw new BaseException(BaseException::BASE_ERROR, '活动已过期或不存在!');
        }

        if($re['receive'] > 0){
            $total = $this->getReceiveTotal($data);
            if($re['receive'] < $total + 1){
                throw new BaseException(BaseException::BASE_ERROR, '超过每人领取限制!');
            }
        }

        if($re['residue_num'] <= 0 ){
            throw new BaseException(BaseException::BASE_ERROR, '您来晚了，券已被领光!');
        }

        $start_time = (int)$re['receive_after_day'] == 0 ? $re['receive_start_time'] : time();
        $end_time = (int)$re['receive_after_day'] == 0 ? $re['receive_end_time'] : strtotime("+{$re['receive_after_day']} day");

        $cate_string = '';
        if($re['goods_type'] == CouponConstants::COUPON_GOODS_TYPE_CATEGORY){
            $cate = $this->couponGoodsRepository->getRows(['coupon_id'=>$data['id']],['params_id']);
            $cate = array_column($cate, 'params_id');
            $cate_string = implode(',', $cate);
        }
        $_data = [
            'member_id'=>$data['member_id'],
            'coupon_id'=>$data['id'],
            'num'=>1,
            'send_way'=>CouponConstants::COUPON_SEND_WAY_MEMBER,
            'start_time'=>$start_time,
            'end_time'=>$end_time,
            'goods_type'=>$re['goods_type'],
            'goods_category'=>$cate_string,
            'free_type'=>$re['free_type'],
        ];


        DB::beginTransaction();
        try {
            $return = parent::baseAdd($_data);
            // 活动减少券库存
            $this->couponRepository->receiveCoupon($_data['coupon_id'], $_data['num']);
            DB::commit();
        }catch (\Exception $e){
            DB::rollBack();
            throw new BaseException(BaseException::BASE_ERROR, $e->getMessage());
        }

        return $return;
    }

    /**
     * Notes: 获取单个活动用户领取的总数
     * Author: Bruce.z
     * DateTime: 2022/9/8 10:43
     * @param $data
     * @return int|mixed|string|void
     */
    private function getReceiveTotal($data)
    {
        return $this->model->newQuery()
            ->where('member_id', $data['member_id'])
            ->where('coupon_id', $data['id'])
            ->sum('num');
    }

    /**
     * Notes: 会员领取的优惠券列表
     * Author: Bruce.z
     * DateTime: 2022/9/13 10:50
     * @param array $condition
     * @param int $page
     * @param int $size
     * @return array
     */
    public function memberCoupon(array $condition, int $page, int $size):array
    {
        $field = ['coupon_id','id','num','status','start_time','end_time','goods_type','free_type','goods_category'];
        $res = $this->getPageRows($condition, $field, $page, $size);
        if ($res['total'] > 0){
            $ids = array_column($res['data'], 'coupon_id');
            $coupons = $this->couponRepository->getRows(['id'=>$ids], ['id','name','coupon_price','price']);
            $coupons = array_column($coupons, null, 'id');

            foreach ($res['data'] as &$re){
                $re['name'] = $coupons[$re['coupon_id']]['name']??'';
                $re['coupon_price'] = $coupons[$re['coupon_id']]['coupon_price']??0;
                $re['price'] = $coupons[$re['coupon_id']]['price']??0;
                $re['start_time'] = date('Y-m-d H:i:s', $re['start_time']);
                $re['end_time'] = date('Y-m-d H:i:s', $re['end_time']);
            }
        }

        return $res;
    }

    /**
     * Notes: 活动 发放列表
     * Author: Bruce.z
     * DateTime: 2022/9/15 14:07
     * @param $coupon_id
     * @param $page
     * @param $size
     * @return array
     */
    public function getList($coupon_id, $page, $size): array
    {
        $condition = ['coupon_id'=>$coupon_id];
        $field = ['coupon_id','id','num','status','start_time','end_time','goods_type','free_type','member_id','create_time'];
        $res = $this->getPageRows($condition, $field, $page, $size);
        if ($res['total'] > 0){
            $ids = array_column($res['data'], 'coupon_id');
            $coupons = $this->couponRepository->getRows(['id'=>$ids], ['id','name','coupon_price','price']);
            $coupons = array_column($coupons, null, 'id');

            $member_ids = array_column($res['data'], 'member_id');
            $members = $this->memberService->getRows(['id'=>$member_ids],['id', 'username','image','tel']);
            $members = array_column($members, null, 'id');
            foreach ($res['data'] as &$re){
                $re['name'] = $coupons[$re['coupon_id']]['name']??'';
                $re['coupon_price'] = $coupons[$re['coupon_id']]['coupon_price']??0;
                $re['price'] = $coupons[$re['coupon_id']]['price']??0;
                $re['start_time'] = date('Y-m-d H:i:s', $re['start_time']);
                $re['end_time'] = date('Y-m-d H:i:s', $re['end_time']);
                $re['member'] = $members[$re['member_id']];
            }
        }

        return $res;
    }
}
